using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Globalization;

using ASPNETLibrary.WebParts.Resources;

namespace ASPNETLibrary.WebParts
{
    /// <summary>
    /// This class will validate ASP.NET controls on skineed parts.
    /// </summary>
    internal sealed class SkinnedPartControlsValidator
    {
        #region [RequiredControl class]
        /// <summary>
        /// This class will be used for SkinnedPart's controls validation. 
        /// It holds a reference to an ASP.NET control and its ID.
        /// </summary>
        internal class RequiredControl
        {
            #region [Private members]

            private Control _childControl;
            private string _controlID;

            #endregion [Private members]

            #region [Properties]
            
            public Control ChildControl
            {
                get
                {
                    return this._childControl;
                }
            }

            public string ControlID
            {
                get
                {
                    return this._controlID;
                }
            }
            
            #endregion [Properties]

            #region [Constructor]
            public RequiredControl(Control childControl, string controlID)
            {
                this._controlID = controlID;
                this._childControl = childControl;
            }
            #endregion [Constructor]
        }
        #endregion [RequiredControl class]

        #region [Methods]

        #region [IsControlValid]
        /// <summary>
        /// This method will check if <paramref name="control"/> parameter is 
        /// null or not and in case it is null the method will set <paramref name="errorMessage"/> 
        /// to next value: "The control with ID '{0}' is not present in the skin. This control must be present in the skin!"
        /// ({0} will be replaced with the value of <paramref name="controlID"/> parameter).
        /// </summary>
        /// <param name="control">Control to be validated</param>
        /// <param name="controlID">The ID of ASP.NET control that should be present in skin</param>
        /// <param name="errorMessage">This parameter will be set to String.Empty in case control is initialized and
        /// it will be set to an error message in case control is not initialized (null).</param>
        /// <returns>Returns true in case control is initialized (not null) and false otherwise.</returns>
        private static bool IsControlValid(Control control, string controlID, out string errorMessage)
        {
            bool retVal = true;
            errorMessage = String.Empty;

            InputParametersValidator.ValidateStringNotEmpty(controlID, "controlID");

            if (control == null)
            {
                errorMessage =
                    String.Format(CultureInfo.InvariantCulture, BaseSkinnedWebPartResources.ControlNotValidErrorMessage, controlID);
                retVal = false;
            }

            return retVal;
        }
        #endregion [IsControlValid]

        #region [ControlsValid]
        /// <summary>
        /// This method will validate a list of ASP.NET controls. If at least one of the controls in
        /// list is not initialized (is null) then whole validation will fail and method will return false.
        /// </summary>
        /// <param name="controls">A list of RequiredControl instances holding controls that will
        /// be validated.</param>
        /// <param name="errorMessage">This parameter will be set to String.Empty in case all controls 
        /// are initialized and it will be set to an error message in case at least one control is 
        /// not initialized.</param>
        /// <returns>Returns true in case all controls are valid and false otherwise</returns>
        public static bool ControlsValid(List<RequiredControl> controls, out string errorMessage)
        {
            bool retVal = true;
            errorMessage = String.Empty;

            InputParametersValidator.ValidateObjectParameter(controls, "controls");

            bool firstErrorMessage = true;
            for (int currentControlIndex = 0; currentControlIndex < controls.Count; currentControlIndex++)
            {
                RequiredControl requiredControl = controls[currentControlIndex];
                string currentErrorMessage;
                bool controlValid = SkinnedPartControlsValidator.IsControlValid(requiredControl.ChildControl, requiredControl.ControlID, out currentErrorMessage);
                if (!controlValid)
                {
                    retVal = false;
                    if (firstErrorMessage)
                    {
                        firstErrorMessage = false;
                    }
                    else
                    {
                        errorMessage += " ";
                    }
                    errorMessage += currentErrorMessage;
                }
            }
            return retVal;
        }
        #endregion [ControlsValid]

        #endregion [Methods]
    }
}
